const { v4: uuidv4 } = require('uuid');

/**
 * 投资者基类 - 所有投资者类型的父类
 */
class Investor {
  /**
   * 创建投资者实例
   * @param {Object} config - 投资者配置
   */
  constructor(config = {}) {
    this.id = config.id || uuidv4();
    this.name = config.name || `Investor-${this.id.substring(0, 8)}`;
    this.capital = config.capital || 10000;
    this.initialCapital = this.capital;
    this.positions = new Map(); // assetId -> {quantity, avgPrice}
    this.rationality = config.rationality !== undefined ? config.rationality : 0.8; // 理性程度 [0,1]
    this.riskTolerance = config.riskTolerance || 0.5; // 风险容忍度 [0,1]
    this.strategy = config.strategy || null; // 交易策略
    this.isBankrupt = false; // 是否破产
    
    // 止盈止损参数
    this.takeProfitProbability = config.takeProfitProbability || 0.3; // 止盈概率
    this.stopLossProbability = config.stopLossProbability || 0.4; // 止损概率
    this.takeProfitThreshold = config.takeProfitThreshold || 0.15; // 止盈阈值 (15%)
    this.stopLossThreshold = config.stopLossThreshold || 0.10; // 止损阈值 (10%)
  }

  /**
   * 获取投资者持仓
   * @param {string} assetId - 资产ID
   * @returns {Object} 持仓信息
   */
  getPosition(assetId) {
    return this.positions.get(assetId) || { quantity: 0, avgPrice: 0 };
  }

  /**
   * 更新投资者持仓
   * @param {string} assetId - 资产ID
   * @param {number} quantityChange - 数量变化
   * @param {number} price - 交易价格
   */
  updatePosition(assetId, quantityChange, price) {
    const position = this.getPosition(assetId);
    
    const newQuantity = position.quantity + quantityChange;
    
    if (newQuantity > 0) {
      // 计算新的平均价格
      if (quantityChange > 0) {
        // 买入
        const totalCost = position.quantity * position.avgPrice + quantityChange * price;
        position.avgPrice = totalCost / newQuantity;
      }
      position.quantity = newQuantity;
      this.positions.set(assetId, position);
    } else if (newQuantity === 0) {
      // 清空持仓
      this.positions.delete(assetId);
    } else {
      // 卖出超过持有量（不允许）
      throw new Error("Cannot sell more than owned");
    }
  }

  /**
   * 更新资本
   * @param {number} amount - 资本变化量
   */
  updateCapital(amount) {
    this.capital += amount;
    
    // 检查是否破产
    if (this.capital <= 0) {
      this.isBankrupt = true;
    }
  }

  /**
   * 获取投资者总资产价值
   * @param {Map} marketPrices - 市场价格映射 assetId -> price
   * @returns {number} 总资产价值
   */
  getTotalValue(marketPrices) {
    let totalValue = this.capital;
    
    for (const [assetId, position] of this.positions) {
      const marketPrice = marketPrices.get(assetId) || 0;
      totalValue += position.quantity * marketPrice;
    }
    
    return totalValue;
  }

  /**
   * 检查是否需要止盈止损
   * @param {Map} marketPrices - 市场价格映射 assetId -> price
   * @returns {Array} 需要平仓的资产列表
   */
  checkTakeProfitAndStopLoss(marketPrices) {
    const assetsToClose = [];
    
    // 机构投资者不执行止盈止损
    if (this.getType() === 'InstitutionalInvestor') {
      return assetsToClose;
    }
    
    for (const [assetId, position] of this.positions) {
      const marketPrice = marketPrices.get(assetId) || 0;
      if (position.quantity > 0 && position.avgPrice > 0) {
        const profitLossRatio = (marketPrice - position.avgPrice) / position.avgPrice;
        
        // 检查止盈条件
        if (profitLossRatio >= this.takeProfitThreshold) {
          if (Math.random() < this.takeProfitProbability) {
            assetsToClose.push({ assetId, action: 'takeProfit' });
          }
        }
        // 检查止损条件
        else if (profitLossRatio <= -this.stopLossThreshold) {
          if (Math.random() < this.stopLossProbability) {
            assetsToClose.push({ assetId, action: 'stopLoss' });
          }
        }
      }
    }
    
    return assetsToClose;
  }

  /**
   * 根据投资者的风险属性计算挂单价格波动范围
   * @returns {number} 价格波动范围
   */
  getPriceVariationRange() {
    // 风险容忍度越高，价格波动范围越大
    return this.riskTolerance * 0.1; // 最大10%的价格波动
  }

  /**
   * 决策方法 - 由子类或策略实现
   * @param {MarketEnvironment} market - 市场环境
   * @returns {Order|null} 订单或null
   */
  decide(market) {
    if (this.strategy && !this.isBankrupt) {
      return this.strategy.decide(market, this);
    }
    return null;
  }

  /**
   * 获取投资者类型
   * @returns {string} 投资者类型
   */
  getType() {
    return this.constructor.name;
  }
  
  /**
   * 检查是否破产
   * @returns {boolean} 是否破产
   */
  getIsBankrupt() {
    return this.isBankrupt;
  }
}

module.exports = Investor;